package com.company.loganalyzer.controller;

import com.company.loganalyzer.dto.ToolInput;
import com.company.loganalyzer.dto.ToolResult;
import com.company.loganalyzer.tools.LogAnalysisTool;
import com.company.loganalyzer.tools.ToolRegistry;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 日志分析控制器
 * 
 * 提供日志分析相关的REST API接口
 */
@RestController
@RequestMapping("/api/v1/log-analysis")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "日志分析", description = "日志分析相关API")
public class LogAnalysisController {

    private final ToolRegistry toolRegistry;

    /**
     * 执行日志分析
     */
    @PostMapping("/analyze")
    @Operation(summary = "执行日志分析", description = "根据输入参数自动选择合适的工具进行日志分析")
    public Mono<ResponseEntity<Map<String, Object>>> analyze(@RequestBody ToolInput input) {
        return Mono.fromCallable(() -> {
            log.info("收到日志分析请求: {}", input);
            
            // 自动选择最佳工具
            Optional<LogAnalysisTool> selectedTool = toolRegistry.selectBestTool(input);
            
            if (selectedTool.isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                    "status", "error",
                    "message", "未找到合适的分析工具",
                    "timestamp", LocalDateTime.now()
                ));
            }
            
            return Map.of("tool", selectedTool.get());
        })
        .flatMap(result -> {
            if (result instanceof ResponseEntity) {
                return Mono.just((ResponseEntity<Map<String, Object>>) result);
            }
            
            @SuppressWarnings("unchecked")
            Map<String, Object> toolMap = (Map<String, Object>) result;
            LogAnalysisTool tool = (LogAnalysisTool) toolMap.get("tool");
            
            return tool.execute(input)
                .map(toolResult -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("status", "success");
                    response.put("toolUsed", tool.getName());
                    response.put("result", toolResult);
                    response.put("timestamp", LocalDateTime.now());
                    
                    return ResponseEntity.ok(response);
                })
                .onErrorReturn(ResponseEntity.status(500).body(Map.of(
                    "status", "error",
                    "message", "工具执行失败",
                    "timestamp", LocalDateTime.now()
                )));
        });
    }

    /**
     * 使用指定工具进行分析
     */
    @PostMapping("/tools/{toolName}")
    @Operation(summary = "使用指定工具分析", description = "使用指定的工具进行日志分析")
    public Mono<ResponseEntity<Map<String, Object>>> analyzeWithTool(
            @Parameter(description = "工具名称") @PathVariable String toolName,
            @RequestBody ToolInput input) {
        
        return Mono.fromCallable(() -> {
            log.info("使用工具 {} 进行分析: {}", toolName, input);
            
            Optional<LogAnalysisTool> tool = toolRegistry.getTool(toolName);
            if (tool.isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of(
                    "status", "error",
                    "message", "工具不存在: " + toolName,
                    "timestamp", LocalDateTime.now()
                ));
            }
            
            return tool.get();
        })
        .flatMap(result -> {
            if (result instanceof ResponseEntity) {
                return Mono.just((ResponseEntity<Map<String, Object>>) result);
            }
            
            LogAnalysisTool tool = (LogAnalysisTool) result;
            
            return tool.execute(input)
                .map(toolResult -> {
                    Map<String, Object> response = new HashMap<>();
                    response.put("status", "success");
                    response.put("toolUsed", tool.getName());
                    response.put("result", toolResult);
                    response.put("timestamp", LocalDateTime.now());
                    
                    return ResponseEntity.ok(response);
                })
                .onErrorReturn(ResponseEntity.status(500).body(Map.of(
                    "status", "error",
                    "message", "工具执行失败",
                    "timestamp", LocalDateTime.now()
                )));
        });
    }

    /**
     * 智能查询接口
     */
    @GetMapping("/query")
    @Operation(summary = "智能查询", description = "通过自然语言查询进行日志分析")
    public Mono<ResponseEntity<Map<String, Object>>> query(
            @Parameter(description = "查询语句") @RequestParam String q,
            @Parameter(description = "时间范围") @RequestParam(required = false) String timeRange,
            @Parameter(description = "服务名") @RequestParam(required = false) String serviceName) {
        
        ToolInput input = ToolInput.builder()
            .query(q)
            .timeRange(timeRange)
            .serviceName(serviceName)
            .build();
        
        return analyze(input);
    }

    /**
     * 获取可用工具列表
     */
    @GetMapping("/tools")
    @Operation(summary = "获取工具列表", description = "获取所有可用的分析工具信息")
    public ResponseEntity<Map<String, Object>> getAvailableTools() {
        Map<String, Object> response = new HashMap<>();
        response.put("status", "success");
        response.put("tools", toolRegistry.getToolInfoList());
        response.put("suggestions", toolRegistry.getToolUsageSuggestions());
        response.put("statistics", toolRegistry.getRegistryStatistics());
        response.put("timestamp", LocalDateTime.now());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 获取工具详细信息
     */
    @GetMapping("/tools/{toolName}")
    @Operation(summary = "获取工具信息", description = "获取指定工具的详细信息")
    public ResponseEntity<Map<String, Object>> getToolInfo(
            @Parameter(description = "工具名称") @PathVariable String toolName) {
        
        Optional<LogAnalysisTool> tool = toolRegistry.getTool(toolName);
        
        if (tool.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        
        LogAnalysisTool t = tool.get();
        Map<String, Object> toolInfo = new HashMap<>();
        toolInfo.put("name", t.getName());
        toolInfo.put("description", t.getDescription());
        toolInfo.put("supportedParameters", t.getSupportedParameters());
        toolInfo.put("priority", t.getPriority());
        toolInfo.put("timeoutSeconds", t.getTimeoutSeconds());
        
        Map<String, Object> response = new HashMap<>();
        response.put("status", "success");
        response.put("tool", toolInfo);
        response.put("timestamp", LocalDateTime.now());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 工具选择建议
     */
    @PostMapping("/tools/suggest")
    @Operation(summary = "工具选择建议", description = "根据输入参数推荐合适的工具")
    public ResponseEntity<Map<String, Object>> suggestTools(@RequestBody ToolInput input) {
        List<LogAnalysisTool> suggestedTools = toolRegistry.selectTools(input);
        
        Map<String, Object> response = new HashMap<>();
        response.put("status", "success");
        response.put("suggestedTools", suggestedTools.stream()
            .map(tool -> Map.of(
                "name", tool.getName(),
                "description", tool.getDescription(),
                "priority", tool.getPriority()
            ))
            .toList());
        response.put("timestamp", LocalDateTime.now());
        
        return ResponseEntity.ok(response);
    }
}